# -*- coding: utf-8 -*-
"""
Created on Mon Jan 22 13:06:52 2018

@author: Matt
"""

from numpy import *
from os import listdir
import operator


# 2.1.2 k-近邻算法 分类器
# classify0 有四个输入参数：用于分类的输入向量inX ， 输入的训练样本集dataSet
#       标签向量为labels，选择最近邻居数目K
# 代码注释见kNN.py
def classify0(inX, dataSet, labels, K):
    dataSetSize = dataSet.shape[0]
    # 距离计算
    diffMat = tile(inX, (dataSetSize, 1)) - dataSet
    sqDiffMat = diffMat ** 2
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances ** 0.5
    sortedDistIndicies = distances.argsort()
    classCount = {}
    for i in range(K):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
    sortedClassCount = sorted(classCount.items(),
                              key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]


def img2vector(filename):
    returnVect = zeros((1, 1024))
    returnMat = zeros((32, 32))
    fr = open(filename)
    for i in range(32):
        lineStr = fr.readline()
        for j in range(32):
            returnVect[0, 32 * i + j] = int(lineStr[j])
            returnMat[i, j] = int(lineStr[j])
    return returnVect  # ,returnMat


# Test One
# testVector,testMat=img2vector('digits/testDigits/2_13.txt')

def handwritingClassTest():
    #获取目录信息
    hwLabels = []
    trainingFileList = listdir('digits/trainingDigits')
    m = len(trainingFileList)
    trainingMat = zeros((m, 1024)) #m行1024列
    for i in range(m):
        #解析出分类数字
        fileNameStr = trainingFileList[i]
        fileStr = fileNameStr.split('.')[0]
        classNumStr = int(fileStr.split('_')[0])
        hwLabels.append(classNumStr)
        trainingMat[i, :] = img2vector('digits/trainingDigits/%s' % fileNameStr)
    testFileList = listdir('digits/testDigits')
    errorCount = 0.0
    mTest = len(testFileList)
    for i in range(mTest):
        fileNameStr = testFileList[i]
        fileStr = fileNameStr.split('.')[0]
        classNumStr = int(fileStr.split('_')[0])
        vectorUnderTest = img2vector('digits/testDigits/%s' % fileNameStr)
        #                                    待判断的向量、训练集合、已知答案、相邻元素个数
        classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)
        # print ("the classifier came back with: %d,the real answer is :%d" % (classifierResult,classNumStr))
        if classifierResult != classNumStr:
            errorCount += 1
    print('\nthe total number of error is : %d ' % errorCount)
    print('\nthe total error rate is : %f %% ' % (errorCount / (float(mTest)/100)))


handwritingClassTest()
